home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / cawf404.zip / string.c < prev   
C/C++ Source or Header  |  1993-12-07  |  7KB  |  351 lines

  1. /*
  2.  *    string.c - string support functions for cawf(1)
  3.  */
  4.  
  5. /*
  6.  *    Copyright (c) 1991 Purdue University Research Foundation,
  7.  *    West Lafayette, Indiana 47907.  All rights reserved.
  8.  *
  9.  *    Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
  10.  *    University Computing Center.  Not derived from licensed software;
  11.  *    derived from awf(1) by Henry Spencer of the University of Toronto.
  12.  *
  13.  *    Permission is granted to anyone to use this software for any
  14.  *    purpose on any computer system, and to alter it and redistribute
  15.  *    it freely, subject to the following restrictions:
  16.  *
  17.  *    1. The author is not responsible for any consequences of use of
  18.  *       this software, even if they arise from flaws in it.
  19.  *
  20.  *    2. The origin of this software must not be misrepresented, either
  21.  *       by explicit claim or by omission.  Credits must appear in the
  22.  *       documentation.
  23.  *
  24.  *    3. Altered versions must be plainly marked as such, and must not
  25.  *       be misrepresented as being the original software.  Credits must
  26.  *       appear in the documentation.
  27.  *
  28.  *    4. This notice may not be removed or altered.
  29.  */
  30.  
  31. #include "cawf.h"
  32. #include <ctype.h>
  33.  
  34. _PROTOTYPE(static void Setroman,());
  35.  
  36.  
  37. /*
  38.  * Asmname(s, c) - assemble name
  39.  */
  40.  
  41. Asmname(s, c)
  42.     unsigned char *s;        /* pointer to name */
  43.     unsigned char *c;        /* code destination (c[3]) */
  44. {
  45.  
  46.     c[1] = c[2] = '\0';
  47.     while (*s && *s == ' ')
  48.         s++;
  49.     if ((c[0] = *s) == '\0')
  50.         return(0);
  51.     return(((c[1] = s[1]) == '\0') ? 1 : 2);
  52. }
  53.  
  54.  
  55. /*
  56.  * Delstr(sx) - delete string
  57.  */
  58.  
  59. void
  60. Delstr(sx)
  61.     int sx;                /* string index */
  62. {
  63.     char buf[MAXLINE];        /* message buffer */
  64.  
  65.     if (sx >= Nstr) {
  66.         (void) sprintf(buf, " bad Delstr(%d) index", sx);
  67.         Error(FATAL, LINE, buf, NULL);
  68.     }
  69.     Free(&Str[sx].str);
  70.     while (sx < (Nstr - 1)) {
  71.         Str[sx] = Str[sx + 1];
  72.         sx++;
  73.     }
  74.     Nstr--;
  75. }
  76.  
  77.  
  78. /*
  79.  * Endword() - end a word
  80.  */
  81.  
  82. void
  83. Endword()
  84. {
  85.     if (Fontstat != 'R')
  86.         Setroman();
  87.     Word[Wordx] = '\0';
  88. }
  89.  
  90.  
  91. /*
  92.  * Findchar(nm, l, s, e) - find special character definition and
  93.  *               optionally enter it
  94.  */
  95.  
  96. Findchar(nm, l, s, e)
  97.     unsigned char *nm;        /* character name */
  98.     int l;                /* effective length */
  99.     unsigned char *s;        /* value string */
  100.     int e;                /* 0 = find, don't enter
  101.                      * 1 = don't find, enter */
  102. {
  103.     int cmp, hi, low, mid;
  104.     unsigned char c[3];
  105.  
  106.     c[0] = nm[0];
  107.     c[1] = (nm[1] == ' ' || nm[1] == '\t') ? '\0' : nm[1];
  108.     c[2] = '\0';
  109.     low = mid = 0;
  110.     hi = Nsch - 1;
  111.     while (low <= hi) {
  112.         mid = (low + hi) / 2;
  113.         if ((cmp = strncmp((char *)c, (char *)Schar[mid].nm, 2)) < 0)
  114.             hi = mid - 1;
  115.         else if (cmp > 0)
  116.             low = mid + 1;
  117.         else {
  118.             if ( ! e)
  119.                 return(mid);
  120.             Free(&Schar[mid].str);
  121.             goto new_char;
  122.         }
  123.     }
  124.     if ( ! e)
  125.         return(-1);
  126.     if (Nsch >= MAXSCH)
  127.         Error(FATAL, LINE, " at character table limit", NULL);
  128.     if (Nsch) {
  129.         if (cmp > 0)
  130.             mid++;
  131.         for (hi = Nsch - 1; hi >= mid; hi--)
  132.             Schar[hi+1] = Schar[hi];
  133.     }
  134.     Nsch++;
  135.     Schar[mid].nm[0] = c[0];
  136.     Schar[mid].nm[1] = c[1];
  137.  
  138. new_char:
  139.  
  140.     Schar[mid].str = Newstr(s);
  141.     Schar[mid].len = l;
  142.     return(mid);
  143. }
  144.  
  145.  
  146. /*
  147.  * Findhy(s, l, e) - find and optionally enter hyphen
  148.  */
  149.  
  150. Findhy(s, l, e)
  151.     unsigned char *s;        /* value string */
  152.     int l;                /* equivalent length */
  153.     int e;                /* 0 = find, don't enter
  154.                      * 1 = enter, don't find */
  155. {
  156.     int i;
  157.  
  158.     for (i = 0; i < Nhy; i++) {
  159.         if (Font[0] == Hychar[i].font)
  160.             break;
  161.     }
  162.     if (i >= Nhy) {
  163.         if ( ! e)
  164.             return(-1);
  165.         if (Nhy >= MAXHYCH)
  166.             Error(FATAL, LINE, " at hyphen limit for font ",
  167.                 (char *)Font);
  168.         Hychar[i].font = Font[0];
  169.         Nhy++;
  170.     } else {
  171.         if ( ! e)
  172.             return(i);
  173.         Error(WARN, LINE, " duplicate hyphen for font ", (char *)Font);
  174.         Free(&Hychar[i].str);
  175.     }
  176.     Hychar[i].str = Newstr(s);
  177.     Hychar[i].len = l;
  178.     return(i);
  179. }
  180.  
  181.  
  182. /*
  183.  * Findstr(nm, s, e) - find and  optionally enter string in Str[]
  184.  */
  185.  
  186. unsigned char *
  187. Findstr(nm, s, e)
  188.     unsigned char *nm;        /* 2 character string name */
  189.     unsigned char *s;        /* string value */
  190.     int e;                /* 0 = find, don't enter
  191.                      * 1 = enter, don't find */
  192. {
  193.     unsigned char c[3];        /* character buffer */
  194.     int cmp, hi, low, mid;        /* binary search controls */
  195.     int i;                /* temporary indexes */
  196.     unsigned char *s1, *s2;        /* temporary string pointers */
  197.  
  198.     c[0] = nm[0];
  199.     c[1] = (nm[1] == ' ' || nm[1] == '\t') ? '\0' : nm[1];
  200.     c[2] = '\0';
  201.     low = mid = 0;
  202.     hi = Nstr - 1;
  203.     Sx = -1;
  204.     while (low <= hi) {
  205.         mid = (low + hi) / 2;
  206.         if ((cmp = strncmp((char *)c, (char *)Str[mid].nm, 2)) < 0)
  207.             hi = mid - 1;
  208.         else if (cmp > 0)
  209.             low = mid + 1;
  210.         else {
  211.             Sx = mid;
  212.             if ( ! e)
  213.                 return(Str[mid].str);
  214.             Free(&Str[mid].str);
  215.             goto new_string;
  216.         }
  217.     }
  218.     if ( ! e)
  219.         return((unsigned char *)"");
  220.     if (Nstr >= MAXSTR)
  221.         Error(FATAL, LINE, " out of space for string ", (char *)c);
  222.     if (Nstr) {
  223.         if (cmp > 0)
  224.             mid++;
  225.         for (hi = Nstr - 1; hi >= mid; hi--)
  226.             Str[hi+1] = Str[hi];
  227.     }
  228.     Nstr++;
  229.     Sx = mid;
  230.     Str[mid].nm[0] = c[0];
  231.     Str[mid].nm[1] = c[1];
  232.  
  233. new_string:
  234.  
  235.     if (s == NULL)
  236.         return (Str[mid].str = Newstr((unsigned char *)""));
  237.     i = (*s == '"') ? 1 : 0;
  238.     s1 = Str[mid].str = Newstr(s + i);
  239.     if (i) {
  240.         s2 = s1 + strlen((char *)s1);
  241.         if (s2 > s1 && *(s2-1) == '"')
  242.             *(s2-1) = '\0';
  243.     }
  244.     return(s1);
  245. }
  246.  
  247.  
  248. /*
  249.  * Setroman() - set Roman font
  250.  */
  251.  
  252. static void
  253. Setroman()
  254. {
  255.     int i;
  256.  
  257.     if ((Wordx + Fstr.rl) >= MAXLINE)
  258.         Error(WARN, LINE, " word too long", NULL);
  259.     else {
  260.         if (Fstr.r) {
  261.             for (i = 0; i < Fstr.rl; i++) {
  262.                 Word[Wordx++] = Fstr.r[i];
  263.             }
  264.             }
  265.         Fontstat = 'R';
  266.     }
  267. }
  268.  
  269.  
  270. /*
  271.  * Str2word(s, len) - copy len characters from string to Word[]
  272.  */
  273.  
  274. Str2word(s, len)
  275.     unsigned char *s;
  276.     int len;
  277. {
  278.     int i;
  279.  
  280.     for (; len > 0; len--, s++) {
  281.         switch (Font[0]) {
  282.         case 'B':
  283.             if (Fontctl == 0) {
  284.                 if ((Wordx + 5) >= MAXLINE) {
  285. word_too_long:
  286.                     Error(WARN, LINE, " word too long",
  287.                         NULL);
  288.                     return(1);
  289.                 }
  290.                 Word[Wordx++] = Trtbl[(int)*s];
  291.                 Word[Wordx++] = '\b';
  292.                 Word[Wordx++] = Trtbl[(int)*s];
  293.                 Word[Wordx++] = '\b';
  294.                 Word[Wordx++] = Trtbl[(int)*s];
  295.                 break;
  296.             }
  297.             if (Fontstat != 'B') {
  298.                 if (Fontstat != 'R')
  299.                     Setroman();
  300.                 if ((Wordx + Fstr.bl) >= MAXLINE)
  301.                     goto word_too_long;
  302.                 if (Fstr.b) {
  303.                     for (i = 0; i < Fstr.bl; i++) {
  304.                         Word[Wordx++] = Fstr.b[i];
  305.                     }
  306.                 }
  307.                 Fontstat = 'B';
  308.             }
  309.             if ((Wordx + 1) >= MAXLINE)
  310.                 goto word_too_long;
  311.             Word[Wordx++] = Trtbl[(int)*s];
  312.             break;
  313.         case 'I':
  314.             if (isalnum(*s)) {
  315.                 if (Fontctl == 0) {
  316.                     if ((Wordx + 3) >= MAXLINE)
  317.                         goto word_too_long;
  318.                     Word[Wordx++] = '_';
  319.                     Word[Wordx++] = '\b';
  320.                     Word[Wordx++] = Trtbl[(int)*s];
  321.                     break;
  322.                 }
  323.                 if (Fontstat != 'I') {
  324.                     if (Fontstat != 'R')
  325.                         Setroman();
  326.                     if ((Wordx + Fstr.itl) >= MAXLINE)
  327.                         goto word_too_long;
  328.                     if (Fstr.it) {
  329.                         for (i = 0; i < Fstr.itl; i++) {
  330.                         Word[Wordx++] = Fstr.it[i];
  331.                         }
  332.                     }
  333.                     Fontstat = 'I';
  334.                 }
  335.                 if ((Wordx + 1) >= MAXLINE)
  336.                     goto word_too_long;
  337.                 Word[Wordx++] = Trtbl[(int)*s];
  338.                 break;
  339.             }
  340.             /* else fall through */
  341.         default:
  342.             if (Fontstat != 'R')
  343.                 Setroman();
  344.             if ((Wordx + 1) >= MAXLINE)
  345.                 goto word_too_long;
  346.             Word[Wordx++] = Trtbl[(int)*s];
  347.         }
  348.     }
  349.     return(0);
  350. }
  351.